package com.sugon.modules.mold.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.ModuleArchivesDao;
import com.sugon.dao.ModuleMaintainPlanItemDao;
import com.sugon.entity.*;
import com.sugon.modules.base.consts.SysApproveStatusConst;
import com.sugon.modules.base.model.dto.HandleApproveResult;
import com.sugon.modules.base.model.vo.ProcessProgressConst;
import com.sugon.modules.base.service.impl.AbstractErmsBaseApproveManager;
import com.sugon.modules.device.consts.ExceptionSourceType;
import com.sugon.modules.mold.consts.MoldPmTicketProgressConst;
import com.sugon.modules.mold.consts.MoldStatusChangeAction;
import com.sugon.modules.mold.model.dto.MoldMaintenancePlanRelationDTO;
import com.sugon.modules.mold.model.vo.DispatchParamVO;
import com.sugon.modules.mold.model.vo.MoldMaintenancePlanDelayApplyParamVO;
import com.sugon.modules.mold.model.vo.MoldMaintenancePlanExceptionReportParam;
import com.sugon.modules.mold.model.vo.MoldMaintenancePlanItemResultParam;
import com.sugon.modules.mold.service.IMoldArchivesManager;
import com.sugon.modules.mold.service.IMoldMaintenanceManager;
import com.sugon.modules.sys.consts.ProcessProgressStatus;
import com.sugon.modules.sys.service.INoticeManager;
import com.sugon.service.*;
import com.sugon.utils.ProcessInfoEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ： YuXD
 * @description： 模具维护业务Manager实现类
 * @date ： 2020-08-13 上午 10:50
 * @version: 1.0
 */
@Service
public class MoldMaintenanceManagerImpl extends AbstractErmsBaseApproveManager implements IMoldMaintenanceManager {

    @Autowired
    private ModuleMaintainRelateService moduleMaintainRelateService;
    @Autowired
    private ModuleMaintainPlanItemService moduleMaintainPlanItemService;
    @Autowired
    private ModuleMaintainPlanItemDao moduleMaintainPlanItemDao;
    @Autowired
    private MaintaPlanChangeRecordsService maintaPlanChangeRecordsService;
    @Autowired
    private ModuleMaintainPlanService moduleMaintainPlanService;
    @Autowired
    private SysProcessInfoService processInfoService;
    @Autowired
    private SysMsgService msgService;
    @Autowired
    private ModuleArchivesDao moduleArchivesDao;
    @Autowired
    private IMoldArchivesManager moldArchivesManager;
    @Autowired
    private ModuleStatusChangeRecordService moduleStatusChangeRecordService;
    @Autowired
    private INoticeManager noticeManager;

    /**
     * addModuleMaintenancePlanItem
     *
     * @param map
     * @return
     */
    @Override
    public String addModuleMaintenancePlanItem(Map<String, Object> map) {
        // 添加结果
        String result = "";
        // 获取维护计划ID
        String planID = MapUtil.getStr(map, "planID");
        // 获取模具维护项，多个维护项用逗号分隔
        String opIDS = MapUtil.getStr(map, "opIDS");
        if (StrUtil.isEmpty(planID) || StrUtil.isEmpty(opIDS)) {
            result = "维护计划或维修项必选！";
        } else {
            String[] moduleMaintenanceOptionList = opIDS.split(",");
            ModuleMaintainPlanItemEntity moduleMaintainPlanItem;
            for (String moduleMaintenanceOptionId : moduleMaintenanceOptionList) {
                //判断是否存在于数据库
                if (!moduleMaintainPlanItemService.isExists(planID, moduleMaintenanceOptionId)) {
                    moduleMaintainPlanItem = new ModuleMaintainPlanItemEntity(planID, moduleMaintenanceOptionId);
                    moduleMaintainPlanItemService.save(moduleMaintainPlanItem);
                }
            }
        }
        return result;
    }

    /**
     * addLastTimeModuleMaintenanceItem
     *
     * @param moduleMaintainPlan
     * @return
     */
    @Override
    public String addLastTimeModuleMaintenanceItem(ModuleMaintainPlanEntity moduleMaintainPlan) {
        // 获取模具编码
        String moldId = moduleMaintainPlan.getMoldId();
        // 校验模具是否已维护过
        List<MoldMaintenancePlanRelationDTO> lastActionEdModuleMaintenancePlanList = moduleMaintainPlanItemDao.queryLastedModuleMaintenancePlanList(moldId);
        if (CollectionUtil.isEmpty(lastActionEdModuleMaintenancePlanList)) {
            return "模具[" + moldId + "]尚未维护过，请手动选择！";
        }
        // 获取第一条已执行过的模具维护计划
        MoldMaintenancePlanRelationDTO moduleMaintenancePlan = lastActionEdModuleMaintenancePlanList.get(0);
        // 获取维护项列表
        List<String> maintenancePlanItemIdList = moduleMaintenancePlan.getMaintenancePlanItemIdList();
        for (String maintenancePlanItemId : maintenancePlanItemIdList) {
            // 根据模具维护计划ID和维护项校验是否存在
            Map<String, Object> param = new HashMap<>(2);
            param.put("opID", maintenancePlanItemId);
            param.put("planID", moduleMaintainPlan.getId());
            // 校验是否已存在关联，只在不存在的情形下创建
            if (moduleMaintainRelateService.queryIsHave(param) == 0) {
                moduleMaintainRelateService.save(new ModuleMaintainPlanItemEntity(moduleMaintainPlan.getId(), maintenancePlanItemId));
            }
        }
        return "";
    }

    /**
     * applyChange
     *
     * @param moldMaintenancePlanDelayApplyParam
     * @return
     */
    @Override
    public boolean applyChange(MoldMaintenancePlanDelayApplyParamVO moldMaintenancePlanDelayApplyParam) {
        MaintaPlanChangeRecordsEntity maintaPlanChangeRecords = new MaintaPlanChangeRecordsEntity();
        maintaPlanChangeRecords.setInitiator(moldMaintenancePlanDelayApplyParam.getApplier());
        maintaPlanChangeRecords.setCreater(moldMaintenancePlanDelayApplyParam.getApplier());
        maintaPlanChangeRecords.setInitiationTime(new Date());
        maintaPlanChangeRecords.setApprovalStatus("0");
        if (maintaPlanChangeRecordsService.save(maintaPlanChangeRecords) > 0) {
            String PlanId = maintaPlanChangeRecords.getModelMaintaPlanId();
            ModuleMaintainPlanEntity planEntity = new ModuleMaintainPlanEntity();
            planEntity.setId(PlanId);
            planEntity.setIsDelay(1);
            moduleMaintainPlanService.update(planEntity);
        }
        return true;
    }

    /**
     * addDevMaintenanceException
     *
     * @param moldMaintenancePlanExceptionReportParam 模具定期维护过程中发现的异常信息
     * @return
     */
    @Override
    public boolean addDevMaintenanceException(MoldMaintenancePlanExceptionReportParam moldMaintenancePlanExceptionReportParam) {
//        // 获取设备详情
//        DevMaintenWorkEntity devMaintenanceTicket = devMaintenWorkService.queryObject(devRepairExceptionParam.getRepairTicketId());
//        Assert.notNull(devMaintenanceTicket, "设备维护工单信息不存在");
//        // 获取设备详情
//        DeviceInfoEntity deviceInfo = deviceInfoService.queryObject(devMaintenanceTicket.getDevId());
//        Assert.notNull(deviceInfo, "设备信息不存在");
//        // 保存异常记录信息
        ExcepRecordEntity excepRecord = new ExcepRecordEntity();
//        BeanUtil.copyProperties(devRepairExceptionParam, excepRecord);
        excepRecord.setExType(ExceptionSourceType.REPAIR);
//        excepRecord.setDevId(deviceInfo.getId());
//        excepRecord.setWorkshopId(deviceInfo.getDevFarm());
//        excepRecord.setDutyUserId(devRepairExceptionParam.getPlanExecutorId());
//        excepRecord.setCreateUser(devRepairExceptionParam.getPlanExecutorId());
//        return excepRecordService.save(excepRecord) > 0;
        return true;
    }

    /**
     * confirmRepair
     *
     * @param moduleMaintainTicket 模具维护工单
     * @return
     */
    @Override
    public boolean confirmRepair(ModuleMaintainPlanEntity moduleMaintainTicket) {
        moduleMaintainTicket.setProgress(MoldPmTicketProgressConst.START_REPAIR);
        moduleMaintainTicket.setActionDate(DateUtil.date());
        // 更新模具状态以及保存变更记录
        if (moduleMaintainPlanService.update(moduleMaintainTicket) > 0) {
            // 1、更新模具状态为维修
            ModuleArchivesEntity moduleArchives = moduleArchivesDao.queryObject(moduleMaintainTicket.getMoldId());
            cn.hutool.core.lang.Assert.notNull(moduleArchives, "模具[{}]不存在，请确认！", moduleMaintainTicket.getMoldId());
            // 2、保存模具状态变更信息
            if (moduleStatusChangeRecordService.checkMoldStatusChangable(moduleArchives.getId(), MoldStatusChangeAction.MAINTENANCE)) {
                moldArchivesManager.changeStatusByMoldId(moduleArchives.getId(), null, MoldStatusChangeAction.MAINTENANCE);
            }
        }
        return true;
    }

    /**
     * completeDevMaintenanceOption
     *
     * @param moduleMaintainPlanItem 模具维护工单项
     * @return
     */
    @Override
    public boolean completeDevMaintenanceOption(ModuleMaintainPlanItemEntity moduleMaintainPlanItem) {
//        devMaintenanceTicketItemEntity.setImplementDate(cn.hutool.core.date.DateUtil.date());
//        devMaintenanceTicketItemEntity.setStatus(1);
//        // 更新设备维护工单项状态
//        if (devMaintenanceTicketItemService.update(devMaintenanceTicketItemEntity) > 0) {
//            String devMaintenanceTicketId = devMaintenanceTicketItemEntity.getDevMainTicketId();
//            /*
//                获取当前维护工单的状态
//                如果是非维护中的状态：那么需要更新工单状态、接收时间和执行时间字段
//                如果是维护中状态：校验是否所有的工单项都结束？如果是那么更新工单状态为已完成
//             */
//            DevMaintenanceTicketEntity devMaintenanceTicket = devMaintenanceTicketService.queryObject(devMaintenanceTicketItemEntity.getDevMainTicketId());
//            if (devMaintenanceTicket.getStatus() > DevMaintenanceTicketStatus.MAINTAINING) {
//                return true;
//            }
//            if (DevMaintenanceTicketStatus.WAIT_EXECUTE.equals(devMaintenanceTicket.getStatus())) {
//                // 校验工单是否刚刚开始，如果是，则修改接单时间和开始时间
//                int completedNum = devMaintenanceTicketItemDao.countTicketOptionNum(devMaintenanceTicketId, 1);
//                if (completedNum == 1) {
//                    devMaintenanceTicket.setStatus(DevMaintenanceTicketStatus.MAINTAINING);
//                    devMaintenanceTicket.setAcceptTime(cn.hutool.core.date.DateUtil.date());
//                    devMaintenanceTicket.setExecuteTime(devMaintenanceTicket.getAcceptTime());
//                    devMaintenanceTicketService.update(devMaintenanceTicket);
//                }
//            }
//            // 校验工单的所有维护项是否已完成，如果已完成，那么修改工单状态为已完成
//            int uncompletedNum = devMaintenanceTicketItemDao.countTicketOptionNum(devMaintenanceTicketId, 0);
//            if (uncompletedNum == 0) {
//                devMaintenanceTicket.setStatus(DevMaintenanceTicketStatus.COMPLETE);
//                devMaintenanceTicket.setCompleteTime(cn.hutool.core.date.DateUtil.date());
//                return devMaintenanceTicketService.update(devMaintenanceTicket) > 0;
//            }
//        }
        return false;
    }

    /**
     * addMaintenanceRecord
     *
     * @param moldMaintenancePlanItemResultParam 模具维护计划项维护记录信息
     * @return
     */
    @Override
    public boolean addMaintenanceRecord(MoldMaintenancePlanItemResultParam moldMaintenancePlanItemResultParam) {
        ModuleMaintainPlanItemEntity moduleMaintainPlanItem = moldMaintenancePlanItemResultParam.getModuleMaintainPlanItem();
        Assert.notNull(moduleMaintainPlanItem, "维护计划项不存在！");
        CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true);
        BeanUtil.copyProperties(moldMaintenancePlanItemResultParam, moduleMaintainPlanItem, copyOptions);
        moduleMaintainPlanItem.setImplementUser(moldMaintenancePlanItemResultParam.getExecutor());
        moduleMaintainPlanItem.setImplementDate(DateUtil.date());
        moduleMaintainPlanItem.setIsExecuted(1);
        if (moduleMaintainPlanItemService.update(moduleMaintainPlanItem) > 0) {
            String planId = moduleMaintainPlanItem.getMaintainPlan();
            ModuleMaintainPlanEntity moduleMaintainPlan = moduleMaintainPlanService.queryObject(planId);
            // 调整模具维护状态
            if (moduleMaintainPlan.getProgress() != MoldPmTicketProgressConst.START_REPAIR) {
                moduleMaintainPlan.setProgress(MoldPmTicketProgressConst.START_REPAIR);
            }
            // 设置维护执行日期
            if (moduleMaintainPlan.getActionDate() == null) {
                moduleMaintainPlan.setActionDate(DateUtil.date());
                /*
                    一般认为执行模具维护计划时
                    开始维护的第一项维护就是模具的最近一次维护的开始时间
                    调整模具状态、模具最近一次模次统计 + 最近一次维护时间
                 */
                moldArchivesManager.doMoldPm(moduleMaintainPlan.getMoldId());
            }
            moduleMaintainPlanService.update(moduleMaintainPlan);
        }
        return true;
    }

    /**
     * commitApprove
     *
     * @param moduleMaintainPlan 模具定期维护计划
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean commitApprove(ModuleMaintainPlanEntity moduleMaintainPlan) {
        moduleMaintainPlan.setProgress(MoldPmTicketProgressConst.DEPT_APPROVING);
        boolean flag = moduleMaintainPlanService.update(moduleMaintainPlan) > 0;
        if (flag) {
            String maintainPlanId = moduleMaintainPlan.getId();
            // 保存流程信息
            processInfoService.saveProcessInfo(maintainPlanId, ProcessInfoEnum.MDE_DQWH, 0, null);
            // 添加备件审批事项
            msgService.addApproveItem(ProcessInfoEnum.MDE_DQWH, maintainPlanId, null, 0);
        }
        return flag;
    }

    /**
     * handleWorkshopApprove
     *
     * @param approveItemId 审批事项ID
     * @param approveStatus 审批状态
     * @param remark        审批备注
     * @return
     */
    @Override
    public HandleApproveResult handleWorkshopApprove(String approveItemId, Integer approveStatus, String remark) {
        HandleApproveResult handleApproveResult = new HandleApproveResult();
        ModuleMaintainPlanEntity moduleMaintainPlan = moduleMaintainPlanService.queryObject(approveItemId);
        Assert.notNull(moduleMaintainPlan, "模具定期维护计划信息不存在，请确认！");
        // 校验规程进度
        Assert.isTrue(MoldPmTicketProgressConst.DEPT_APPROVING.equals(moduleMaintainPlan.getProgress()), "只可以审核处于审核中的维护计划！");
        moduleMaintainPlan.setRemark(remark);
        // 如果审核通过
        if (approveStatus == SysApproveStatusConst.PASSED) {
            moduleMaintainPlan.setProgress(MoldPmTicketProgressConst.CALL_REPAIR);
            int rows = moduleMaintainPlanService.update(moduleMaintainPlan);
            if (rows > 0) {
                handleApproveResult.setProcessProgressStatus(ProcessProgressStatus.END);
                handleApproveResult.setTitle(moduleMaintainPlan.getPlanName());
                handleApproveResult.setNextNodeLevel(0);
            }
        } else if (approveStatus == SysApproveStatusConst.NOT_PASSED) {
            moduleMaintainPlan.setProgress(ProcessProgressConst.NOT_PASSED);
            int rows = moduleMaintainPlanService.update(moduleMaintainPlan);
            if (rows > 0) {
                handleApproveResult.setProcessProgressStatus(ProcessProgressStatus.ING);
                handleApproveResult.setTitle(moduleMaintainPlan.getPlanName());
                handleApproveResult.setUserId(moduleMaintainPlan.getCreateUser());
            }
        }
        return handleApproveResult;
    }

    /**
     * dispatch
     *
     * @param dispatchParam
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean dispatch(DispatchParamVO dispatchParam) {
        /*
        1、更新模具维护计划接收人信息
        2、给维修工发消息
         */
        ModuleMaintainPlanEntity moduleMaintainPlan = dispatchParam.getModuleMaintainPlan();
        moduleMaintainPlan.setRepairUser(dispatchParam.getRepairUser());
        moduleMaintainPlan.setProgress(MoldPmTicketProgressConst.DISPATCH);
        if (moduleMaintainPlanService.update(moduleMaintainPlan) > 0) {
            // 向维修工的ICHANGAN和企业微信发送维护通知
            noticeManager.pushMoldMaintenanceNotice(dispatchParam.getId());
        }
        return true;
    }

}
